package org.springblade.common.tool;


import java.util.concurrent.*;

/**
 * 线程池工具类
 * 后面引入框架监控
 * @author lijiamin
 */
public abstract class ThreadPoolUtils {

	private static ThreadPoolExecutor pool = null;

	/**
	 * 无响应执行
	 * @param runnable
	 */
	public static void execute(Runnable runnable) {
		getThreadPool().execute(runnable);
	}

	/**
	 * 有响应执行
	 * @param callable
	 * @param <T>
	 * @return
	 */
	public static <T> Future<T> submit(Callable<T> callable) {
		return getThreadPool().submit(callable);
	}

	/**
	 * 创造线程池
	 * @return
	 */
	public static synchronized ThreadPoolExecutor getThreadPool() {
		if (pool == null) {
			// 获取处理器数量
			int cpuNum = Runtime.getRuntime().availableProcessors();
			// 根据cpu数量,计算出合理的线程并发数
			// 最佳线程数目 = （（线程等待时间+线程CPU时间）/线程CPU时间 ）* CPU数目
			int maximumPoolSize = cpuNum * 2 + 1;
			// 七个参数
			// 1. 核心线程数
			// 2. 最大线程数
			// 3. 空闲线程最大存活时间
			// 4. 时间单位
			// 5. 阻塞队列
			// 6. 创建线程工厂
			// 7. 拒绝策略
			pool = new ThreadPoolExecutor(maximumPoolSize - 1,
				maximumPoolSize,
				5,
				TimeUnit.SECONDS,
				new ArrayBlockingQueue<>(50),
				Executors.defaultThreadFactory(),
				new ThreadPoolExecutor.AbortPolicy());
		}
		return pool;
	}

	/**
	 * 多线程异步执行同任务
	 * 缺点：关于异常管控的操作不够完善
	 * @param threadNum
	 */
	public void multithreadingAsync(int threadNum) {
		for (int i = 0; i < threadNum; i++) {
			CompletableFuture.runAsync(() -> {
				try {
					runTask();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}, getThreadPool());
		}
	}

	/**
	 * 抽象任务执行
	 */
	public abstract void runTask();
}

